# Vote represents a user's 
class Vote < ActiveRecord::Base
  belongs_to :user
  belongs_to :issue

  # a user can only vote once
  validates_uniqueness_of :user_id, :scope => :issue_id

  # creates or changes the user's vote for the issue to 'for'
  def self.for( issue, user )
    if v = find( :first, :conditions =>
        ['user_id = ? AND issue_id = ?', user, issue] )
      v.update_attribute :positive, true
      v
    else
      create( :positive => true, :issue => issue, :user => user )
    end
  end

  # creates or changes the user's vote for the issue to 'against'
  def self.against( issue, user )
    if v = find( :first, :conditions =>
        ['user_id = ? AND issue_id = ?', user, issue] )
      v.update_attribute :positive, false
      v
    else
      create( :positive => false, :issue => issue, :user => user )
    end
  end

  # returns the total number of positive votes minus the total number of
  # negative votes for a user (his/her "disposition")
  def self.disposition_of( user )
    ( count( :conditions => ['user_id = ? AND positive = ?', user, true] ) -
      count( :conditions => ['user_id = ? AND positive = ?', user, false] ) )
  end

  # returns the total number of positive votes minus the total number of
  # negative votes for an issue (its "popularity")
  def self.popularity_of( issue )
    ( count( :conditions => ['issue_id = ? AND positive = ?', issue, true] ) -
      count( :conditions => ['issue_id = ? AND positive = ?', issue, false] ) )
  end

  def self.voted_for?( issue, user )
    v = Vote.find( :first, :conditions => [ 'user_id = ? AND issue_id = ?', user, issue ] )
    ( v and v.for? )
  end

  def self.voted_against?( issue, user )
    v = Vote.find( :first, :conditions => [ 'user_id = ? AND issue_id = ?', user, issue ] )
    ( v and v.against? )
  end

  def for?
    self.positive?
  end

  def negative?
    !self.positive?
  end
  alias against? negative?

  def inspect
    "Vote( #{user.display} #{self.send( :for? ) ? 'for' : 'against' } #{issue.project.name} ##{issue.local_id} )"
  end
end
